#define _CRT_SECURE_NO_WARNINGS 1
#include"string.h"
namespace zkz
{
	const size_t string::npos = -1;//涓嶈〃鏄庡湪绫婚噷鐨勮瘽灏辨壘涓嶅埌

	string::iterator string::begin()  //娉ㄦ剰杩欓噷鐨剆tring::iterator 锛堢被涓殑typedef锛?
	{
		return _str;
	}
	string::iterator string::end()
	{
		return _str + _size;
	}
	string::const_iterator string::begin() const
	{
		return _str;
	}
	string::const_iterator string::end() const
	{
		return _str + _size;
	}

	string::string(const string& s)  //实现深拷贝
	{
		_str = new char[s._capacity + 1];     //拷贝构造是用一个已存在对象给新对象初始化，所以不需要释放新对象的空间
		memcpy(_str, s._str, _size + 1);      //即不必像拷贝构造一样，直接开块空间给新对象就行了
		_size = s._size;
		_capacity = s._capacity;
	}
	string& string::operator=(const string& s)  //比较模糊，需要 回看 赋值重载--》已解决
	{
		if (this != &s)//比较地址，看是不是自己赋值自己
		{
			char* tmp = new char[s._capacity + 1];    //赋值是两个已存在对象之间的拷贝，所以深拷贝要开新空间
			memcpy(tmp, s._str, _size + 1);
			delete[] _str;

			_str = tmp;
			_size = s._size;
			_capacity = s._capacity;
		}
		return *this;
	}
	const char* string::c_str()
	{
		return _str;
	}
	size_t string::size()const
	{
		return _size;
	}
	size_t string::capacity()const
	{
		return _capacity;
	}
	char& string::operator[](size_t x)
	{
		return _str[x];
		//return *(_str + x);
	}
	const char& string::operator[](size_t x)const
	{
		return _str[x];
		//return *(_str + x);
	}
	bool string::operator<(string& str)
	{
		int len1 = _size;
		int len2 = str._size;
		int i1 = 0, i2 = 0;

		while (i1 < len1 && i2 < len2)
		{
			if (_str[i1] < str[i2])
				return true;
			else if (_str[i1] > str[i2])
				return false;
			else
			{
				i1++;
				i2++;
			}
		}
		return i1 == len1 && i2 < len2;
	}
	bool string::operator>=(string& str)
	{
		return !(*this < str);
	}
	bool string::operator>(string& str)
	{
		return *this != str && *this >= str;
	}
	bool string::operator<=(string& str)
	{
		return !(*this > str);
	}
	bool string::operator==(string& str)
	{
		//直接用strcmp的话字符串内部如果有\0就会截断，所以要自己实现
		//用memcmp比内存的值吗？不，memcmp需要知道比较的字节数
		//所以取字符，一个个比啦
		int len1 = _size;
		int len2 = str._size;
		int i1 = 0, i2 = 0;

		while (i1 < len1 && i2 < len2)
		{
			if (_str[i1] != str[i2])
				return false;
			else
			{
				i1++;
				i2++;
			}
		}
		return true;

	}
	bool string::operator!=(string& str)
	{
		return !(*this == str);
	}

	void string::reserve(size_t n)
	{
		if (n > _capacity)//鎵╁
		{
			char* tmp = new char[n + 1];
<<<<<<< HEAD
			memcpy(tmp, _str, _size + 1);
			delete[] _str;//原本忘记写了
=======
			memcpy(tmp, _str, _size+1);
			delete[] _str;//鍘熸湰蹇樿鍐欎簡
>>>>>>> c9bb92c011126c1cc8e82e9be1a25ed6ca483f5d
			_str = tmp;
			_capacity = n;
		}
	}

	void string::push_back(char x)
	{
		if (_size == _capacity)//鎵╁
		{
			size_t new_capacity = _capacity == 0 ? 4 : 2 * _capacity;
			reserve(new_capacity);
		}
		_str[_size++] = x;
		_str[_size] = '\0';
	}

	void string::append(const char* str)
	{
		assert(str);
		size_t len = strlen(str);
		if (_size + len > _capacity)
		{
			size_t new_capacity = _size + len > 2 * _capacity ? _size + len : 2 * _capacity;
			reserve(new_capacity);
			/*                        //閿欒鍐欐硶锛侊紒杩欐牱鏄笉浼氱湡姝ｅ紑鍐呭瓨鎵╁鐨?
			_capacity = _size + len > 2 * _capacity ? _size + len : 2 * _capacity;
			reserve(capacity);
			*/
		}
		memcpy(_str + _size, str, len + 1);
		_size += len;
	}
	void string::append(string& str)
	{
		size_t len = str._size;
		if (_size + len > _capacity)
		{
			size_t new_capacity = _size + len > 2 * _capacity ? _size + len : 2 * _capacity;
			reserve(new_capacity);//娌℃湁鎵╁锛堥噸寮€绌洪棿锛夌殑璇濓紝鏋愭瀯鏃朵細鍑洪棶棰?
		}
		memcpy(_str + _size, str._str, len + 1);
		_size += len;
	}
	void string::swap(string& s)
	{
		char* tmp = s._str;
		s._str = _str;
		_str = tmp;
	}

	string& string::operator+=(char x)
	{
		push_back(x);
		return *this;
	}
	string& string::operator+=(const char* str)
	{
		append(str);
		return *this;
	}

	size_t string::find(char c, size_t pos) const
	{
		for (size_t i = 0; i < _size; i++)
		{
			if (_str[i] == c)
				return i;
		}
		return npos;
	}
	size_t string::find(const char* s, size_t pos) const //找串，strstr或者KMP(重复多效率高，反之) or BM(实际用的多)
	{
		char* tmp = strstr(_str + pos, s);
		if (tmp == nullptr)
			return npos;
		return tmp - _str;
	}

	string string::substr(size_t pos, size_t len) const
	{
		assert(pos < _size); //pos给负数会怎么样
		string tmp;
		if (len == npos || len > _size)
		{
			for (size_t i = pos; i < _size; i++)
			{
				tmp += _str[i];
			}
			return tmp;
		}

		for (size_t i = 0; i < len; i++)
		{
			tmp += _str[pos + i];
		}
		return tmp;
	}

	void string::insert(size_t pos, char x)
	{
		assert(pos <= _size);
		if (_size == _capacity)
		{
			reserve(_capacity == 0 ? 4 : 2 * _capacity);
		}
		int end = _size;
		while (end >= (int)pos)     //强转解决整型提升的问题
		{
			_str[end + 1] = _str[end];
			end--;
		}
		_str[pos] = x;
		_size++;
	}

	void string::insert(size_t pos, const char* str)
	{
		int len = strlen(str);
		if (_size + len > _capacity)
		{
			size_t new_cap = _size + len > 2 * _capacity ? _size + len : 2 * _capacity;
			reserve(new_cap);
		}
<<<<<<< HEAD
		int end = _size;          // 头插时出问题了，size_t是非负的，会永远>0 ,死循环
		while (end >= (int)pos)         // 并且也并没有真的留出要的空间
=======
		size_t end = _size;  //鏈変釜鍧戯紝鍏充簬size_t鍜屾暣鍨嬫彁鍗?
		while (end >= pos)
>>>>>>> c9bb92c011126c1cc8e82e9be1a25ed6ca483f5d
		{
			_str[end + len] = _str[end];//鐣欏嚭鎻掑叆瀛楃涓茬殑闀垮害
			end--;
		}
		memcpy(_str + pos, str, len);//涓嶈鎷疯礉鈥榎0鈥?
		_size += len;
	}

	void string::erase(size_t pos, size_t len)
	{
<<<<<<< HEAD
		if (len == npos || len >= _size - pos)//pos后(含pos处)全删除
=======
		if (len==npos || len >= _size - pos)//pos鍚?鍚玴os澶?鍏ㄥ垹闄?
>>>>>>> c9bb92c011126c1cc8e82e9be1a25ed6ca483f5d
		{
			_size = pos;
			_str[_size] = '\0';//鍒繕浜?
		}
		else
		{
			memmove(_str + pos, _str + pos + len, _size - pos - len + 1);
		}
		_size -= len;
	}
	void string::clear()
	{
		_size = 0;
		_str[_size] = '\0';
	}

	ostream& operator<<(ostream& os, const string& s)
	{
		for (size_t i = 0; i < s.size(); i++)
		{
			os << s[i];
		}
		return os;
	}

	istream& operator>>(istream& is, string& s)//未完待续
	{
		/*char ch;
		is >> ch;
		while (ch != ' '&& ch != '\n')
		{
			s += ch;
			is >> ch;           //停不下来，因为 >> 取不到空白字符
		}
		return is;*/

		//s.clear();   //有待改进
		//char ch;
		//ch = getchar();
		//while (ch != ' ' && ch != '\n') 
		//{
		//	s += ch;                      //如果输入字符串过长，可能频繁扩容，并且可能出现大面积浪费的情况
		//	ch = getchar();
		//}
		//return is;

		char ch;
		char buffer[256];               //缓冲区,大小可为任意合适值
		ch = is.get();
		int i = 0;
		while (ch != ' ' && ch != '\n')
		{
			if (i == 255)
			{
				buffer[i] = '\0';           //细节处理，在255处放\0
				s += buffer;
				i = 0;
			}
			buffer[i++] = ch;
			ch = is.get();
		}
		buffer[i] = '\0';                   //出来了也要放\0
		s += buffer;
		
		return is;
	}

}